
 #include <Keypad.h>
//#include <LiquidCrystal.h>
#include <LiquidCrystal_I2C.h>

// 1. LCD Pins
//LiquidCrystal lcd(7, 8, 9, 10, 11, 12);
LiquidCrystal_I2C lcd(0x3F, 20, 4); // set the LCD address to 0x27 for a 16 chars and 2 line display

// 2. Keypad Pins
const byte Rows = 4;
const byte Cols = 4;
char keys[Rows][Cols] =
{
  {'1', '2', '3', '+'},
  {'4', '5', '6', '-'},
  {'7', '8', '9', '*'},
  {'C', '0', '=', '/'}
};
byte rowPins[Rows] = {5, 4, 3, 2};
byte colPins[Cols] = {6, 7, 8, 9};
Keypad customKeypad = Keypad(makeKeymap(keys), rowPins, colPins, Rows, Cols);

// 3. Dot Button
int dot = A0;
int dotFlag = 0;
int dotButton = 0;

// 4. Calculator Operators
float num1, num2, fraction;
float total;
char operation, button;

// 5. Loading Setup
char input[16];
int n = 1750;

void setup()
{
  // Initialize dot button as input to Arduino
  pinMode(dot, INPUT);
  Serial.begin(9600);

  // Initialize LCD Size
  //  lcd.begin(16, 2);
  lcd.init();
  lcd.backlight();
  // LCD Loading Setup Begin
  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("LOADING...");
  for (int i = 0; i < 16; i++)
  {
    lcd.setCursor(i, 1);
    lcd.write(255);
    delay(50);
  }
  lcd.clear();
  lcd.setCursor(1, 0);
  lcd.print("Simple Arduino");
  lcd.setCursor(3, 1);
  lcd.print("Calculator");
  delay(n);
  lcd.clear();
  // LCD Loading Setup End
}
void loop()
{
  char customKey = customKeypad.getKey();

  if (customKey) {
    Serial.println(customKey);
  }
  // First while loop for num1.
  while (1)
  {
    dotButton = digitalRead(dot);
    button = customKeypad.getKey();
    if (button == 'C')
    {
      dotFlag = 0;
      num1 = 0;
      num2 = 0;
      fraction = 0;
      total = 0;
      operation = 0;
      lcd.clear();
    }
    else if (dotButton == LOW)
    {
      dotFlag = 1;
    }
    else if (button >= '0' && button <= '9')
    {
      if (dotFlag == 0)
      {
        num1 = num1 * 10 + (button - '0');
        lcd.setCursor(0, 0);
        lcd.print(num1);
      }
      else if (dotFlag == 1)
      {
        fraction = (button - '0');
        num1 = num1 + (fraction / 10);
        lcd.setCursor(0, 0);
        lcd.print(num1);
        dotFlag++;
      }
      else if (dotFlag == 2)
      {
        fraction = (button - '0');
        num1 = num1 + (fraction / 100);
        lcd.setCursor(0, 0);
        lcd.print(num1);
        dotFlag++;
      }
    }
    else if (button == '-' || button == '+' || button == '*' || button == '/')
    {
      operation = button;
      dotFlag = 0;
      lcd.setCursor(15, 0);
      lcd.print(operation);
      break;
    }
  }
  // Second while loop for num2.
  while (1)
  {
    dotButton = digitalRead(dot);
    button = customKeypad.getKey();
    if (button == 'C')
    {
      dotFlag = 0;
      num1 = 0;
      num2 = 0;
      fraction = 0;
      total = 0;
      operation = 0;
      lcd.clear();
      break;
    }
    else if (dotButton == LOW)
    {
      dotFlag = 1;
    }
    else if (button >= '0' && button <= '9')
    {
      if (dotFlag == 0)
      {
        num2 = num2 * 10 + (button - '0');
        lcd.setCursor(0, 1);
        lcd.print(num2);
      }
      else if (dotFlag == 1)
      {
        fraction = (button - '0');
        num2 = num2 + (fraction / 10);
        lcd.setCursor(0, 1);
        lcd.print(num2);
        dotFlag++;
      }
      else if (dotFlag == 2)
      {
        fraction = (button - '0');
        num2 = num2 + (fraction / 100);
        lcd.setCursor(0, 1);
        lcd.print(num2);
        dotFlag++;
      }
    }
    if (button == '=')
    {
      domath();
      break;
    }
  }
  // Third while loop for ensuring C button is executed after while loop 2.
  while (1)
  {
    button = customKeypad.getKey();
    if (button == 'C')
    {
      dotFlag = 0;
      num1 = 0;
      num2 = 0;
      fraction = 0;
      total = 0;
      operation = 0;
      lcd.clear();
      break;
    }
  }
}
void domath()
{
  switch (operation)
  {
    case '+':
      total = num1 + num2;
      break;
    case '-':
      total = num1 - num2;
      break;
    case '/':
      total = num1 / num2;
      break;
    case '*':
      total = num1 * num2;
      break;
  }
  lcd.print('=');
  lcd.clear();
  if (operation == '/' && num2 == 0)
  {
    lcd.print("ERROR 0 DIV");
  }
  else
  {
    lcd.print(total);
  }
}
